package com.wang.experiment.experiment2;

import javafx.util.Pair;
import lombok.AllArgsConstructor;
import lombok.Data;

import java.util.*;

/**
 * @author wr
 * @date 2021/10/13 22:30
 */
public class Three {
    public static void main(String[] args) {
        GradeManager gradeManager = new GradeManager();
        gradeManager.addStudent(new Student("小明", "01", Student.Sex.MALE, "1001"));
        gradeManager.addStudent(new Student("小红", "02", Student.Sex.FEMALE, "1001"));
        gradeManager.addStudent(new Student("小华", "01", Student.Sex.MALE, "1002"));
        gradeManager.addStudent(new Student("小张", "03", Student.Sex.MALE, "1002"));
        gradeManager.addStudent(new Student("小虎", "02", Student.Sex.MALE, "1003"));
        gradeManager.addStudent(new Student("小花", "04", Student.Sex.FEMALE, "1003"));

        gradeManager.addCourse(new Course(1, "高数", 6));
        gradeManager.addCourse(new Course(2, "线代", 3));
        gradeManager.addCourse(new Course(3, "c语言", 2));
        gradeManager.addCourse(new Course(4, "Java程序设计", 5));

        gradeManager.addGrade(new Grade("小明", "高数", 92));
        gradeManager.addGrade(new Grade("小明", "线代", 89));
        gradeManager.addGrade(new Grade("小明", "c语言", 90));
        gradeManager.addGrade(new Grade("小明", "Java程序设计", 99));
        gradeManager.addGrade(new Grade("小红", "高数", 76));
        gradeManager.addGrade(new Grade("小红", "线代", 85));
        gradeManager.addGrade(new Grade("小红", "c语言", 94));
        gradeManager.addGrade(new Grade("小红", "Java程序设计", 37));
        gradeManager.addGrade(new Grade("小华", "高数", 85));
        gradeManager.addGrade(new Grade("小华", "线代", 48));
        gradeManager.addGrade(new Grade("小华", "c语言", 96));
        gradeManager.addGrade(new Grade("小华", "Java程序设计", 27));
        gradeManager.addGrade(new Grade("小张", "高数", 47));
        gradeManager.addGrade(new Grade("小张", "线代", 60));
        gradeManager.addGrade(new Grade("小张", "c语言", 96));
        gradeManager.addGrade(new Grade("小张", "Java程序设计", 79));
        gradeManager.addGrade(new Grade("小虎", "高数", 52));
        gradeManager.addGrade(new Grade("小虎", "线代", 79));
        gradeManager.addGrade(new Grade("小虎", "c语言", 50));
        gradeManager.addGrade(new Grade("小虎", "Java程序设计", 79));
        gradeManager.addGrade(new Grade("小花", "高数", 82));
        gradeManager.addGrade(new Grade("小花", "线代", 89));
        gradeManager.addGrade(new Grade("小花", "c语言", 87));
        gradeManager.addGrade(new Grade("小花", "Java程序设计", 90));

        gradeManager.printStudentGrades();
        gradeManager.printClassGrade();
        gradeManager.printStudentByGradeAsc();
        gradeManager.printCourseAverage();
    }
}

class GradeManager {
    private List<Student> students;
    private List<Course> courses;
    private List<Grade> grades;
    private Set<String> classes;

    public void addStudent(Student s) {
        if (students == null) {
            students = new ArrayList<>();
            classes = new HashSet<>();
        }
        students.add(s);
        classes.add(s.getClassNum());
    }

    public void addCourse(Course c) {
        if (courses == null) {
            courses = new ArrayList<>();
        }
        courses.add(c);
    }

    public void addGrade(Grade g) {
        if (grades == null) {
            grades = new ArrayList<>();
        }
        grades.add(g);
    }

    public void printStudentGrades() {
        for (Student s : students) {
            int sum = 0, course = 0, credit = 0;
            for (Grade g : grades) {
                if (s.getName().equals(g.getStudentName())) {
                    sum += g.getGrade();
                    course++;
                    if (g.getGrade() >= 60) {
                        for (Course c : courses) {
                            if (c.getName().equals(g.getCourseName())) {
                                credit += c.getCredit();
                                break;
                            }
                        }
                    }
                }
            }
            System.out.println(s.getName()
                    + " sum:" + sum
                    + ", average:" + (double) sum / course +
                    ", credit:" + credit);
        }
    }

    public void printClassGrade() {
        for (String classNum : classes) {
            List<Student> classStudent = new ArrayList<>();
            for (Student s : students) {
                if (s.getClassNum().equals(classNum)) {
                    classStudent.add(s);
                }
            }
            int sum = 0, course = 0, credit = 0;
            for (Student s : classStudent) {
                for (Grade g : grades) {
                    if (s.getName().equals(g.getStudentName())) {
                        sum += g.getGrade();
                        course++;
                    }
                }
            }
            System.out.println(classNum + " average:" + (double) sum / course);
        }
    }

    public void printStudentByGradeAsc() {
        List<Pair<Double, String>> stu = new ArrayList<>();
        for (Student s : students) {
            int sum = 0, course = 0;
            for (Grade g : grades) {
                if (s.getName().equals(g.getStudentName())) {
                    sum += g.getGrade();
                    course++;
                }
            }
            stu.add(new Pair<>((double) sum / course, s.getName()));
        }
        stu.sort(new Comparator<Pair<Double, String>>() {
            @Override
            public int compare(Pair<Double, String> o1, Pair<Double, String> o2) {
                return o1.getKey() > o2.getKey() ? -1 : (o1.getKey().equals(o2.getKey()) ? 0 : 1);
            }
        });
        for (Pair<Double, String> s : stu) {
            System.out.println(s.getValue() + " average:" + s.getKey());
        }
    }

    public void printCourseAverage() {
        for (Course c : courses) {
            int sum = 0, num = 0;
            for (Grade g : grades) {
                if (g.getCourseName().equals(c.getName())) {
                    sum += g.getGrade();
                    num++;
                }
            }
            System.out.println(c.getName() + " average:" + (double) sum / num);
        }
    }
}

class Student {
    private String name;
    private String schoolNum;
    private Sex sex;
    private String classNum;

    enum Sex {MALE, FEMALE}

    public Student(String name, String schoolNum, Sex sex, String classNum) {
        this.name = name;
        this.schoolNum = schoolNum;
        this.sex = sex;
        this.classNum = classNum;
    }

    public String getName() {
        return name;
    }

    public String getSchoolNum() {
        return schoolNum;
    }

    public Sex getSex() {
        return sex;
    }

    public String getClassNum() {
        return classNum;
    }
}

class Course {
    private Integer courseNum;
    private String name;
    private Integer credit;

    public Course(Integer courseNum, String name, Integer credit) {
        this.courseNum = courseNum;
        this.name = name;
        this.credit = credit;
    }

    public Integer getCourseNum() {
        return courseNum;
    }

    public String getName() {
        return name;
    }

    public Integer getCredit() {
        return credit;
    }
}

class Grade {
    private String studentName;
    private String courseName;
    private Integer grade;

    public Grade(String studentName, String courseName, Integer grade) {
        this.studentName = studentName;
        this.courseName = courseName;
        this.grade = grade;
    }

    public String getStudentName() {
        return studentName;
    }

    public String getCourseName() {
        return courseName;
    }

    public Integer getGrade() {
        return grade;
    }
}